/*
 * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.dy.yandi.biz.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.dy.yandi.api.client.requirement.model.DesignRequirementHistory;
import com.dy.yandi.api.client.requirement.service.DesignRequirementHistoryService;
import com.dy.yandi.biz.annotation.DesignLog;
import com.pig4cloud.pig.admin.api.dto.UserInfo;
import com.pig4cloud.pig.admin.api.feign.RemoteUserService;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.filter.FieldToEmptyStringFilter;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 操作日志使用spring event异步入库
 *
 * @author L.cm
 */
@Order(Integer.MAX_VALUE)
@Aspect
@Slf4j
@Component
@RequiredArgsConstructor
public class DesignLogAspect {

	private final DesignRequirementHistoryService designRequirementHistoryService;

	private final RemoteUserService remoteUserService;

	@Around("@annotation(designLog)")
	@SneakyThrows
	public Object around(ProceedingJoinPoint point, DesignLog designLog) {
		String strClassName = point.getTarget().getClass().getName();
		String strMethodName = point.getSignature().getName();
		log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
		// 获取入参信息
		Object[] paramsArray = point.getArgs();

		Object obj;
		Long requirementId = 0L;
		try {
			// 获取出参信息
			obj = point.proceed();
			JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj, new FieldToEmptyStringFilter()),JSONObject.class);
			if (Objects.nonNull(jsonObject)) {
				JSONObject data = JSON.parseObject(JSON.toJSONString(jsonObject.get("data")), JSONObject.class);
				if (Objects.nonNull(data) && 0 == Integer.valueOf(String.valueOf(jsonObject.get("code"))) && Objects.nonNull(data.get("id"))) {
					requirementId = Long.valueOf(String.valueOf(data.get("id")));
					DesignRequirementHistory designRequirementHistory = new DesignRequirementHistory();
					designRequirementHistory.setRequirementId(requirementId);
					designRequirementHistory.setRemarkTime(new Date());
					designRequirementHistory.setCreateId(Long.valueOf(SecurityUtils.getUser().getId()));
					designRequirementHistory.setCreateTime(new Date());
					designRequirementHistory.setUpdateTime(new Date());

					R<UserInfo> userinfoR = remoteUserService.findUserByUserId(SecurityUtils.getUser().getId(), SecurityConstants.FROM_IN);
					if (Objects.nonNull(userinfoR)) {
						UserInfo userInfo = userinfoR.getData();
						designRequirementHistory.setRemark(userInfo.getSysUser().getRealName() + designLog.value());
					}
					// 保存信息
					designRequirementHistoryService.save(designRequirementHistory);
				}
			}
		}catch (Exception e) {
			throw e;
		}
		return obj;
	}

	private static String toJson(Object o, String... excludeKeys) {
		List<String> excludes = Arrays.asList(excludeKeys);
		SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
		filter.getExcludes().addAll(excludes);
		return JSON.toJSONString(o, filter);
	}
}

